﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using System.Text.RegularExpressions;
using BfLib.Text;

namespace BfLib.Text
{
    public struct TSectionMatch
    {
        public int StartNum;
        public int EndNum;
        public int Increment;
        public int UrlCount;
        public bool IsFilled;
        public string SectionText;
        public int MinIntegerWidth;
        public bool IsLeadingZeroes;
    }

    public class TextExpander
    {
        private string _startText = string.Empty;
        private StringCollection _urlCollector;

        #region Properties

        public int TotalExpansionSize
        {
            get
            {
                if (this._startText.Length == 0)
                {
                    return 0;
                }
                else
                {
                    return this.GetTotalExpansionSize(this._startText);
                }
            }
        }

        public StringCollection ExpandedUrls
        {
            get
            {
                return _urlCollector;
            }
        }

        #endregion

        public TextExpander(string TextLine)
        {
            _startText = TextLine.Trim();
            _urlCollector = new StringCollection();
            _urlCollector.Add(_startText);

            TSectionMatch sect;

            while (this.StringContainsSection(_urlCollector[0]))
            {
                sect = this.GetSectionFromString(_urlCollector[0], 0);

                if (sect.IsFilled)
                {
                    this.ExpandSections(sect);
                }
            }
        }

        public TextExpander()
        {
            _urlCollector = new StringCollection();
        }

        public void SetStartText(string TextLine)
        {
            _startText = TextLine.Trim();
            _urlCollector.Clear();
            _urlCollector.Add(_startText);

            TSectionMatch sect;

            while (this.StringContainsSection(_urlCollector[0]))
            {
                sect = this.GetSectionFromString(_urlCollector[0], 0);

                if (sect.IsFilled)
                {
                    this.ExpandSections(sect);
                }
            }
        }

        private void ExpandSections(TSectionMatch sect)
        {
            StringCollection urlHolder = new StringCollection();
            if (!sect.IsFilled) return;

            StringLib.ReplaceStringsFirstInstance(ref this._urlCollector, sect.SectionText, "{0}");
            //StringLib.ReplaceStrings(ref urls, sect.SectionText, "{0}", true);

            for (int j = 0; j < this._urlCollector.Count; j++)
            {
                for (int i = 0; i < sect.UrlCount; i++)
                {
                    if (sect.IsLeadingZeroes)
                    {
                        urlHolder.Add(String.Format(this._urlCollector[j], StringLib.PadInt(sect.StartNum + (i * sect.Increment), sect.MinIntegerWidth)));
                    }
                    else
                    {
                        urlHolder.Add(String.Format(this._urlCollector[j], sect.StartNum + (i * sect.Increment)));
                    }
                }
            }

            this._urlCollector = urlHolder;

        }

        #region Private methods

        private bool StringContainsSection(string s)
        {
            return StringLib.RegexpContains(s, @"\[([0-9]*)\-([0-9]*)\ *\,([0-9]*)\ *\]");
        }

        private int GetSectionCount(string s)
        {
            return StringLib.RegexpGetMatchCount(s, @"\[([0-9]*)\-([0-9]*)\ *\,([0-9]*)\ *\]");
        }

        private TSectionMatch GetSectionFromString(string s, int i)
        {
            Regex regex = new Regex(@"\[([0-9]*)\-([0-9]*)\ *\,([0-9]*)\ *\]", RegexOptions.IgnoreCase);
            MatchCollection mc = regex.Matches(s);
            TSectionMatch sect = new TSectionMatch();
            sect.IsFilled=false;

            int StartNumberWidth = 0;
            bool IsLeadingZeroes = false;

            for( int n=0 ; n<mc.Count ; n++ )//Match m in mc)
            {
                if (n == i)
                {
                    sect.StartNum = int.Parse(mc[n].Groups[1].Value);
                    StartNumberWidth = mc[n].Groups[1].Value.Length;
                    IsLeadingZeroes = mc[n].Groups[1].Value[0]=='0';

                    sect.EndNum = int.Parse(mc[n].Groups[2].Value);
                    sect.Increment = int.Parse(mc[n].Groups[3].Value);
                    sect.IsLeadingZeroes = IsLeadingZeroes;
                    sect.MinIntegerWidth = StartNumberWidth;
                    sect.SectionText = mc[n].Groups[0].Value;
 
                    int tmpswapper=sect.StartNum;
                    sect.UrlCount=0;

                    while(tmpswapper<=sect.EndNum )
                    {
                        sect.UrlCount=sect.UrlCount+1;
                        tmpswapper += sect.Increment;
                    }
                    
                    sect.IsFilled=true;
                    return sect;
                }
            }

            return sect;
        }

        private int GetTotalExpansionSize(string s)
        {
            int sect_count = GetSectionCount(s);
            int url_count = 0;

            TSectionMatch match;

            for (int i = 0; i < sect_count; i++)
            {
                match = this.GetSectionFromString(s, i);
                if(match.IsFilled)
                {
                    url_count += match.UrlCount;
                }
            }

            return url_count;
        }

        #endregion
    }
}

